package makeTest

import (
	"fmt"
	"reflect"
)

var i int

type I int

var i1 I

type Test interface {
	Say()
}

type P1 struct {
	Name string
	Age  int64
}

func (P1) Say() {
	fmt.Println("???")
}

type UseStr struct {
	m Test
}

func ReflectTest() {
	model := UseStr{}
	modelI := P1{"ll", 18}

	model.m = &modelI
	fmt.Printf("%#v\n", model.m)
	fmt.Println(reflect.TypeOf(model.m))
	model.m.Say()
	x := newInterfaceModel(model.m)
	fmt.Printf("%#v\n", x)
	fmt.Println(reflect.TypeOf(x))

	modelList := make([]interface{}, 0)
	modelList = append(modelList, &P1{"l1", 15})
	fmt.Printf("%#v\n", modelList)
	fmt.Println(reflect.TypeOf(modelList))

	modelList1 := make([]UseStr, 0)
	x1 := newInterfaceSlice(modelList1)
	fmt.Printf("%#v\n", x1)
	fmt.Println(reflect.TypeOf(x1))
	fmt.Println(reflect.TypeOf(x1).Elem())

	model2 := UseStr{}
	x2 := newInterfaceSlice(&model2)
	fmt.Printf("%#v\n", x2)
	fmt.Println(reflect.TypeOf(x2))
	fmt.Println(reflect.TypeOf(x2).Elem())

}

func newInterfaceModel(m Test) (r Test) {
	modelType := reflect.TypeOf(m).Elem()
	newModel := reflect.New(modelType).Interface()
	return newModel.(Test)
}

func newInterfaceSlice(s interface{}) (r interface{}) {
	modelType := reflect.TypeOf(s)
	slice := reflect.MakeSlice(modelType, 0, 0)
	x := reflect.New(slice.Type())
	x.Elem().Set(slice)
	return x.Interface()
}
